/*
 * Copyright 2007 Jeffrey Palm
 */

import java.io.*;
import java.util.*;

/**
 * Creates a Java world
 */
class JavaSink extends AbstractOOSink {

  JavaSink(File outdir) {super(outdir);}

  // --------------------------------------------------
  // AbstractOOSink
  // --------------------------------------------------

  String typeHeader(World.Type t) {return null;}

  String typeFooter(World.Type t) {return null;}

  boolean wantsPublic() {return true;}

  String getExtends() {return "extends";}

  String formatMember(World.Decl d) {return "private final " + d.getType() + " " + d.getName();}

  String constructorStart(String name) {return name;}

  String methodStart(World.Decl d) {return d.getType();}

  boolean useParamType() {return true;}

  String thiz(String name) {return "this." + name;}

  String var(String name) {return name;}

  String lineComment() {return "//";}

  String comment(String s) {return "/* " + s + " */";}

  String openBrace() {return "{";}
  String closeBrace() {return "}";}

  void createMethodBody(PrintStream out, World.Type t, World.Decl d) {
    out.print(tab + tab + "String res = Support.execute(\"" + t.getName() + "\",\"" + d.getName() + "\",new Support.Param[]{");
    if (d.getParams() != null) {
      boolean first = true;
      for (World.Param p : d.getParams()) {
        if (!first) out.print(",");
        first = false;
        out.print("Support.newParam(\"" + p.getName() + "\",");
        if (p.getType() != null) {
          out.print(p.getName());
        } else {
          out.print("String.valueOf(" + getInvokeMethod(t,d.getParams(),p) + ")");
        }
        out.print(")");
      }
    }
    out.println("});");
    out.println(tab + tab + "return " + wrapResult(d.getType(),"res") + ";");
  }

  // --------------------------------------------------
  // FileSink
  // --------------------------------------------------

  String getFileName(World.Type t) {
    return t.getName() + ".java";
  }

  String name() {
    return "java";
  }

  // --------------------------------------------------
  // Private
  // --------------------------------------------------

  private String wrapResult(String n, String p) {
    if ("boolean".equals(n)) {
      return "\"true\".equals(" + p + ")";
    }
    if ("byte".equals(n)) {
      return "Byte.parseByte(" + p + ")";
    }
    if ("short".equals(n)) {
      return "Short.parseShort(" + p + ")";
    }
    if ("char".equals(n)) {
      return "Char.parseChar(" + p + ")";
    }
    if ("int".equals(n)) {
      return "Integer.parseInt(" + p + ")";
    }
    if ("long".equals(n)) {
      return "Long.parseLong(" + p + ")";
    }
    if ("float".equals(n)) {
      return "Float.parseFloat(" + p + ")";
    }
    if ("double".equals(n)) {
      return "Double.parseDouble(" + p + ")";
    }
    return p;
  }

}